import { IonButton, modalController } from '@ionic/vue';
import axios from 'axios';
import { Util } from 'ibz-core';
import { defineComponent, reactive } from 'vue';

/**
 * 电子签名编辑器输入属性
 *
 * @memberof AppSignatureProps
 */
const AppSignatureProps = {
  /**
   *  值
   * @type {String} value
   * @memberof AppSignatureProps
   */
  value: {
    type: String,
  },

  /**
   *  线宽
   * @type {String} lineWidth
   * @memberof AppSignatureProps
   */
  lineWidth: {
    type: String,
    default: '3',
  },

  /**
   *  线色
   * @type {String} lineColor
   * @memberof AppSignatureProps
   */
  lineColor: {
    type: String,
    default: '#000',
  },

  /**
   *  背景色
   * @type {String} backgroundColor
   * @memberof AppSignatureProps
   */
  backgroundColor: {
    type: String,
    default: '#fff',
  },

  /**
   *  提示信息
   * @type {String} placeholder
   * @memberof AppSignatureProps
   */
  placeholder: {
    type: String,
    default: '开始签名',
  },

  /**
   *  图片名称
   * @type {String} imageName
   * @memberof AppSignatureProps
   */
  imageName: {
    type: String,
    default: '个性签名',
  },

  /**
   *  图片尺寸
   * @type {String} imageSize
   * @memberof AppSignatureProps
   */
  imageSize: {
    type: Object,
    default: {
      width: '100%',
      height: '100%',
    },
  },

  /**
   * 只读状态
   *
   * @type {boolean}
   * @memberof AppUploadProps
   */
  readonly: {
    type: Boolean,
    default: false,
  },

  /**
   * 上下文data数据（表单数据）
   *
   * @type {Object}
   * @memberof AppSignatureProps
   */
  contextData: Object,

  /**
   * 上下文
   *
   * @type {Object}
   * @memberof AppSignatureProps
   */
  context: Object,

  /**
   * 视图参数
   *
   * @type {Object}
   * @memberof AppSignatureProps
   */
  viewParam: Object,

  /**
   * 上传参数
   *
   * @type {Object}
   * @memberof AppSignatureProps
   */
  uploadParam: {
    type: Object,
    default: () => {},
  },

  /**
   * 下载参数
   *
   * @type {Object}
   * @memberof AppSignatureProps
   */
  exportParam: {
    type: Object,
    default: () => {},
  },
};

export const AppSignature = defineComponent({
  name: 'AppSignature',
  props: AppSignatureProps,
  emits: ['editorValueChange'],
  methods: {
    /**
     * @description 开始绘制
     * @param {*} $event
     */
    touchStart($event: any) {
      $event.preventDefault();
      if ($event.touches.length == 1) {
        this.data.isDraw = true; //签名标记
        const obj = {
          x: $event.targetTouches[0].clientX - this.position.offsetLeft,
          y: $event.targetTouches[0].clientY - this.position.offsetTop,
        };
        this.data.startX = obj.x;
        this.data.startY = obj.y;
        this.data.canvasTxt?.beginPath(); //开始作画
      }
    },

    /**
     * @description 绘制路径
     * @param {*} $event
     */
    touchMove($event: any) {
      $event.preventDefault();
      if ($event.touches.length == 1) {
        const obj = {
          x: $event.targetTouches[0].clientX - this.position.offsetLeft,
          y: $event.targetTouches[0].clientY - this.position.offsetTop,
        };
        this.data.moveY = obj.y;
        this.data.moveX = obj.x;
        this.data.canvasTxt.moveTo(this.data.startX, this.data.startY);
        this.data.canvasTxt.lineTo(obj.x, obj.y);
        this.data.canvasTxt.stroke();
        this.data.startX = obj.x;
        this.data.startY = obj.y;
      }
    },

    /**
     * @description 绘制结束
     * @param {*} $event
     */
    touchEnd($event: any) {
      if ($event.touches.length == 0) {
        this.data.canvasTxt?.closePath(); //收笔
      }
    },

    /**
     * @description 确认绘制
     */
    async uploadImage() {
      const imgBase64 = this.canvas.toDataURL();
      const image = Util.dataURLtoFile(imgBase64, this.imageName);
      const params = new FormData();
      params.append('file', image, image.name);
      const config = {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      };
      const response: any = await axios.post(this.uploadUrl, params, config);
      if (response && response.data && response.status === 200) {
        this.$emit('editorValueChange', [response.data]);
      } else {
        App.getNoticeService().error(`${image.name} ${(this as any).$tl('common.upload.uploadfailure', '上传失败')}`);
      }
    },

    /**
     * @description 绘制模态内容
     * @return {*}
     */
    renderModal() {
      return defineComponent({
        render: () => {
          return [
            <ion-header translucent>
              <ion-toolbar>
                <ion-title>{this.imageName}</ion-title>
                <ion-buttons slot='start'>
                  <ion-button onclick={() => this.dismissModal(false)}>
                    {(this as any).$tl('share.cancel', '取消')}
                  </ion-button>
                </ion-buttons>
                <ion-buttons slot='end'>
                  <ion-button onclick={() => this.dismissModal(true)}>
                    {(this as any).$tl('share.ok', '确认')}
                  </ion-button>
                </ion-buttons>
              </ion-toolbar>
            </ion-header>,
            <ion-content fullscreen>
              <div class='signature-canvas-box'>
                <canvas
                  class='signature-canvas'
                  style={{
                    backgroundColor: this.backgroundColor,
                    width: this.imageSize.width,
                    height: this.imageSize.height,
                  }}
                  onTouchstart={($event: any) => {
                    this.touchStart($event);
                  }}
                  onTouchmove={($event: any) => {
                    this.touchMove($event);
                  }}
                  onTouchend={($event: any) => {
                    this.touchEnd($event);
                  }}
                ></canvas>
              </div>
            </ion-content>,
          ];
        },
      });
    },

    /**
     * @description 打开模态
     */
    async openModal() {
      const modal = await modalController.create({
        component: this.renderModal(),
        showBackdrop: true,
        cssClass: 'app-signature-modal',
      });
      await modal.present();
      this.currentModal = modal;
      this.canvas = this.currentModal.querySelector('.signature-canvas');
      this.canvas.height =
        (Object.is(this.imageSize.height, '100%') ? this.canvas.clientHeight : Number.parseInt(this.imageSize.height)) -
        1;
      this.canvas.width =
        (Object.is(this.imageSize.width, '100%') ? this.canvas.clientWidth : Number.parseInt(this.imageSize.width)) - 1;
      this.position.offsetTop = this.canvas.offsetTop;
      this.position.offsetLeft = this.canvas.offsetLeft;
      this.data.canvasTxt = this.canvas.getContext('2d');
      this.data.canvasTxt.strokeStyle = this.lineColor;
      this.data.canvasTxt.lineWidth = Number(this.lineWidth);
    },

    /**
     * @description 关闭模态
     * @param {boolean} $event
     */
    dismissModal($event: boolean) {
      if ($event) {
        this.uploadImage();
      }
      if (this.currentModal) {
        this.currentModal.dismiss().then(() => {
          this.currentModal = null;
        });
      }
    },
  },
  setup(props: any) {
    const environment = App.getEnvironment();
    const uploadUrl: string = `${environment?.UploadFile}`;
    const downloadUrl: string = `${environment?.ExportFile}`;
    const files: any[] = props.value ? JSON.parse(props.value) : [];
    const position: any = {};
    const canvasTxt: any = null;
    const startX: number = 0;
    const startY = 0;
    const moveY = 0;
    const moveX = 0;
    const isDraw = false;
    const currentModal: any = null;
    const canvas: any = null;
    const data = reactive({
      canvasTxt,
      startX,
      startY,
      moveY,
      moveX,
      isDraw,
    });
    return {
      uploadUrl,
      downloadUrl,
      files,
      data,
      position,
      currentModal,
      canvas,
    };
  },
  render() {
    return (
      <div class='app-signature'>
        {this.files?.length > 0
          ? this.files.map((file: any) => {
              return (
                <div class='signature-image'>
                  <img src={file.url}></img>
                </div>
              );
            })
          : null}
        <IonButton
          onClick={() => {
            this.openModal();
          }}
        >
          {this.placeholder}
        </IonButton>
      </div>
    );
  },
});
